/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.blockly.ohos.ui;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;

public class TextVertical extends Text implements Component.DrawTask, Component.EstimateSizeListener {
    private Paint mTextPaint;
    private String mText = "";
    private Rect bounds = new Rect();
    final static int DEFAULT_TEXT_SIZE = 15;
    final static int DEFAULT_TEXT_COLOR = 0xFF000000;
    private int direction;
    private int textSize = DEFAULT_TEXT_SIZE;
    private Color textColor = new Color(DEFAULT_TEXT_COLOR);

    public TextVertical(Context context, AttrSet attrSet) {
        super(context, attrSet);
        if (attrSet.getAttr("text").isPresent()) {
            mText = attrSet.getAttr("text").get().getStringValue();
        }
        if (attrSet.getAttr("text_size").isPresent()) {
            textSize = attrSet.getAttr("text_size").get().getDimensionValue();
        }
        if (attrSet.getAttr("text_color").isPresent()) {
            textColor = attrSet.getAttr("text_color").get().getColorValue();
        }
        if (attrSet.getAttr("direction").isPresent()) {
            String value = attrSet.getAttr("direction").get().getStringValue();
            switch (value) {
                case "downToUp":
                    direction = 1;
                    break;
                default://upToDown
                    direction = 0;
                    break;
            }
        }
        init();
        setEstimateSizeListener(this);
        addDrawTask(this);
        postLayout();
        invalidate();
    }

    private final void init() {
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(textSize);
        mTextPaint.setColor(textColor);
        mTextPaint.setTextAlign(TextAlignment.CENTER);
    }

    public void setText(String text) {
        mText = text;
        postLayout();
        invalidate();
    }

    public void setTextSize(int size) {
        mTextPaint.setTextSize(size);
        postLayout();
        invalidate();
    }

    public void setTextColor(Color color) {
        mTextPaint.setColor(color);
        invalidate();
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        bounds = mTextPaint.getTextBounds(mText);
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setEstimatedSize(EstimateSpec.getSizeWithMode(width, EstimateSpec.PRECISE),
                EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE));
        setWidth(width);
        setHeight(height);
        return true;
    }

    private int measureWidth(int measureSpec) {
        int result;
        int specMode = EstimateSpec.getMode(measureSpec);
        int specSize = EstimateSpec.getSize(measureSpec);
        if (specMode == EstimateSpec.PRECISE) {
            result = specSize;
        } else {
            result = bounds.getHeight();
            if (specMode == EstimateSpec.NOT_EXCEED) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int measureHeight(int measureSpec) {
        int result;
        int specMode = EstimateSpec.getMode(measureSpec);
        int specSize = EstimateSpec.getSize(measureSpec);

        if (specMode == EstimateSpec.PRECISE) {
            result = specSize;
        } else {
            result = bounds.getWidth() + 40;//上下边距
            if (specMode == EstimateSpec.NOT_EXCEED) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        int startX = 0;
        int startY = 0;
        int stopY = getHeight();
        Path path = new Path();
        if (direction == 0) {
            startX = (getWidth() >> 1) - (bounds.getHeight() >> 1);
            path.moveTo(startX, startY);
            path.lineTo(startX, stopY);
        } else {
            startX = (getWidth() >> 1) + (bounds.getHeight() >> 1);
            path.moveTo(startX, stopY);
            path.lineTo(startX, startY);
        }
        canvas.drawTextOnPath(mTextPaint, mText, path, 0, 0);
        Paint paint = new Paint();
        paint.setColor(Color.GRAY);
        paint.setStrokeWidth(1);
        canvas.drawRect(0, 0, getWidth(), 5, paint);
        canvas.drawRect(getWidth() - 5, 0, getWidth(), getHeight(), paint);
        canvas.drawRect(0, getHeight() - 5, getWidth(), getHeight(), paint);
    }
}
